package com.handpay.framework.swiper;

import android.content.Context;
import android.text.TextUtils;

import com.dynamicode.p27.lib.bluetooth4.DcBleDevice;
import com.dynamicode.p27.lib.inter.CSwiperController;
import com.dynamicode.p27.lib.inter.CSwiperStateChangedListener;
import com.handpay.framework.swiper.ic.IShowSelectApplication;
import com.handpay.framework.utils.CommonUtils;
import com.handpay.zztong.hp.log.HPLog;
import com.mset.cardswiper.Convert;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeoutException;

/**
 * 动联P27蓝牙刷卡器
 * 
 * @author yliang
 * 
 */
public class DynamiCodeP27 extends AbstractBbposSwiper implements CSwiperStateChangedListener {

	private static String TAG = "DynamiCodeP27";
	private static int TRADETYPE_1 = 1;// 查询
	private static int TRADETYPE_2 = 2;// 消费

	private CSwiperController swiperController;
	private Context mContext;
	private String devAddress;
	public boolean mIsSwiperOK = false;
	private String mData = "";
	private IShowSelectApplication selectApplication;
	private SwipeTransData mSwipeTransData;
	private String swiperCSN;
	private String macStr;

	public DynamiCodeP27(Context context, String address, IShowSelectApplication selectApplication) {

		devAddress = address;
		mContext = context;
		this.selectApplication = selectApplication;
		mLock = new AsynSwiperLock();
		mIsSwiperOK = true;
		initSDK();
	}

	public void initSDK() {
		try {
			if (swiperController == null) {
				HPLog.e(TAG, ">>>>ItronSwiper:initSdk<<<<" + swiperController);
				swiperController = new CSwiperController(mContext, this);

				HPLog.e(TAG, ">>>>ItronSwiper:initSdk<<<<" + swiperController);
			}
		} catch (Exception e) {
			HPLog.e(TAG, ">>>>ItronSwiper:initSdk :Exception<<<<" + e);
			e.printStackTrace();

		}

	}

	public boolean connect() {

		try {
			HPLog.e(TAG, "〈〈〈〈〈connect〉〉〉〉〉");
			swiperController.connectDevice(devAddress, 20);
		} catch (Exception e) {
			HPLog.i(TAG, "", e);
			HPLog.e(TAG, "〈〈〈〈〈connect〉〉〉〉〉Exception");
			mIsSwiperOK = false;
		}
		return mIsSwiperOK;
	}

	@Override
	public String getCSN() {
		HPLog.i(TAG, "getCSN()----");
		if (connect()) {

			if (swiperController != null) {
				// 获取设备信息
				swiperController.getDeviceInfo();

				try {
					mLock.lock(20, AsynSwiperLock.GETCSN);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			if (swiperCSN != null) {
				HPLog.i(TAG, "getCSN----" + swiperCSN);

				return swiperCSN;
			}

		}

		return null;
	}

	@Override
	public boolean stopOperation() {
		HPLog.e(TAG, ">>>>stopOperation<<<<");
		mData = null;
		mHTData.clear();
		if (swiperController != null) {
			// 刷卡器发送指令,使刷卡器进入刷卡状态以后接受到该指令退出刷卡状态,进入IDLE状态
			swiperController.stopScan();
			swiperController.stopCSwiper();
		}
		mLock.unlock(AsynSwiperLock.IDLE);
		return true;

	}

	@Override
	public boolean closeDevice() {
		HPLog.e(TAG, ">>>>closeDevice<<<<");
		stopOperation();
		mIsSwiperOK = false;
		mContext = null;
		selectApplication = null;
		if (swiperController != null) {
			// 删除控制器CSwiperController,释放资源
			swiperController.clearSwiperController();
			swiperController = null;
		}
		return true;
	}

	@Override
	public SwipeResult swipeCard(String factor, int timeout) {

		if (swiperController == null) {
			HPLog.i(TAG, "swipeCard:swiperController is null");
			// 当取消处理
			return new SwipeResult(SwipeStatus.SWIPE_CANCEL);
		}
		initTransData(factor, timeout);
		swiperController.startSwiper(TRADETYPE_2, "0", factor, timeout);
		try {
			mLock.lock(timeout, AsynSwiperLock.NEW_SWIPE_CARD);
		} catch (TimeoutException te) {
			HPLog.i(TAG, "", te);
			return new SwipeResult(SwipeStatus.SWIPE_TIMEOUT);
		}
		String cardType = mHTData.get("DW_TRADE");
		if (!TextUtils.isEmpty(cardType)) {
			SwipeResult result = new SwipeResult(SwipeStatus.SWIPE_OK, null);
			result.mCardType = cardType;
			mHTData.remove("DW_TRADE");
			return result;
		}
		if (mHTData.get("cardType") != null && mHTData.get("cardType").equals("00")) {
			// 磁条卡
			// 检查磁条刷卡所必备的数据
			if (null == mHTData.get(IBusinessSwiper.BANK_DYNAMIC_KEY)) {
				HPLog.e(TAG, "no dynamic key");
				return new SwipeResult(SwipeStatus.SWIPE_ERROR);
			}
			if (null == mHTData.get(IBusinessSwiper.BANK_TRACK2_KEY)) {
				HPLog.e(TAG, "no track2");
				return new SwipeResult(SwipeStatus.SWIPE_ERROR);
			}
			if (null == mHTData.get(IBusinessSwiper.BANK_PLAIN_ACCOUNT_KEY)) {
				HPLog.e(TAG, "no plain account");
				return new SwipeResult(SwipeStatus.SWIPE_ERROR);
			}
			SwipeResult result = new SwipeResult(SwipeStatus.SWIPE_OK, mHTData.get(IBusinessSwiper.BANK_PLAIN_ACCOUNT_KEY));
			result.mCardType = mHTData.get("cardType");
			return result;
		} else if (mHTData.get("cardType") != null && mHTData.get("cardType").equals("01")) {
			// IC卡
			mSwipeTransData.isIcTrans = true;
			mData = mHTData.get(IBusinessSwiper.BANK_PLAIN_ACCOUNT_KEY);

			if (null == swiperController) {
				HPLog.i(TAG, "bbpos cancel card");
				// 当取消处理
				return new SwipeResult(SwipeStatus.SWIPE_CANCEL);
			}
			if (TextUtils.isEmpty(mData)) {
				return new SwipeResult(SwipeStatus.SWIPE_ERROR);
			}

			return new SwipeResult(SwipeStatus.SWIPE_OK, mData);
			// return iccStartEmv();

		} else if (null == swiperController) {
			HPLog.i(TAG, "bbpos cancel card");
			// 当取消处理
			return new SwipeResult(SwipeStatus.SWIPE_CANCEL);
		} else {
			// 当做错误处理
			return new SwipeResult(SwipeStatus.SWIPE_ERROR);
		}

		/*
		 * if (null != mHTData.get(IBusinessSwiper.BANK_PLAIN_ACCOUNT_KEY)) {
		 * SwipeResult result = new SwipeResult(SwipeStatus.SWIPE_OK,
		 * mHTData.get(IBusinessSwiper.BANK_PLAIN_ACCOUNT_KEY));
		 * result.mCardType = mHTData.get("cardType"); return result; }
		 * 
		 * if (!isStop) { HPLog.i(TAG, "--isStop--" + isStop); return new
		 * SwipeResult(SwipeStatus.SWIPE_CANCEL); }
		 */

	}

	private void initTransData(String factor, int timeOut) {
		// mHTData，可以在后面完全被SwipeTransData取代
		mHTData.clear();
		mSwipeTransData = new SwipeTransData();
		mSwipeTransData.mBbposICTranIndex = 0;
		mSwipeTransData.mFactor = factor;
		mSwipeTransData.mTimeout = timeOut;
	}

	// 格式化数据 type=0:关键数据 type=1 mac数据
	public String formatData(String data, int type) {
		int len;
		StringBuffer sb = new StringBuffer();
		if (mSwiperMode == SwiperMode.SUPER_TRANS) {
			HPLog.e(TAG, "super");
			sb.append(Convert.bytesToHexString(data.getBytes()));
		} else {
			HPLog.e(TAG, "normal");
			sb.append(Convert.bytesToHexString(CommonUtils.hexStringToBytes(data)));
		}

		if (type == 0) {
			len = sb.length();
			while ((len % 16) > 0) {
				sb.append("00");
				len = sb.length();
			}
		} else if (type == 1) { // mac
			sb.append("80");
			len = sb.length();
			while ((len % 16) > 0) {
				sb.append("00");
				len = sb.length();
			}
			sb.append("8000000000000000");
		}

		return sb.toString();
	}

	@Override
	public String encData(String data, String index, String factor) {

		if (index.equals("13")) {
			float money = Float.parseFloat(data);
			if (money > 0) {
				HPLog.e(TAG, "我大于0了-----" + money);
			} else {
				HPLog.e(TAG, "我小于0了-----" + money);
			}

		}

		HPLog.e(TAG, "encData-data: " + data + " index: " + index);
		factor = factor.substring(0, factor.length() - 2);
		HPLog.e(TAG, factor);
		if (ISwiperListener.KeyDataIndex.equals(index)) {
			data = formatData(data, 0);
			// data = formatDataAdpu(data);
			HPLog.e(TAG, "encData-data: " + data);
			mData = swiperController.encryptData(data);
			HPLog.e(TAG, "加密后data:" + mData);
			return mData;
		} else if (PIN_INDEX.equals(index)) {

			mData = swiperController.encryptPin(data);
			HPLog.e(TAG, "加密后PIN:" + mData);
			return mData;
		} else if (ISwiperListener.MacDataIndex.equals(index)) {
			String macplain = null;
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			try {
				bos.write(String.valueOf(data.toCharArray()).getBytes());
				bos.write(0x80);
				while (bos.size() % 8 != 0) {
					bos.write(0x00);
				}
				bos.write(0x80);
				for (int i = 0; i < 7; i++) {
					bos.write(0x00);
				}
				byte[] macPlainBytes = bos.toByteArray();
				macplain = CommonUtils.bytesToHexString(macPlainBytes);
			} catch (IOException ioe) {
				HPLog.e(TAG, "", ioe);
				try {
					bos.close();
				} catch (IOException e) {
					HPLog.e(TAG, "", e);
				}
			}
			HPLog.e(TAG, "加密前Mac:" + macplain);
			// CommandReturn commandReturn = itcommm.Get_MAC(0,
			// 1,Util.HexToBin(factor), Util.HexToBin(macplain));
			macStr = swiperController.calcMac(macplain, factor);
			HPLog.e(TAG, "加密后Mac:" + macStr);
			return macStr;
		}
		return null;
	}

	@Override
	public Hashtable<String, String> batchEncData(Hashtable<Integer, String> htDatas, String factor) {
		return null;
	}

	@Override
	public boolean isSwiperReady() {
		return mIsSwiperOK;
	}

	@Override
	public SwiperModel getSwiperModel() {
		return SwiperModel.P27_BLUETOOTH;
	}

	@Override
	public void onCardSwipeDetected() {
		HPLog.i(TAG, "onCardSwipeDetected");
	}

	@Override
	public void onDeviceConnected() {
		HPLog.i(TAG, "onDeviceConnected");
		// 连接刷卡器回调
		swiperController.getDeviceInfo();
	}

	@Override
	public void onDeviceConnectedFailed() {
		HPLog.i(TAG, "onDeviceConnectedFailed---连接失败");

	}

	@Override
	public void onDeviceDisconnected() {
		HPLog.i(TAG, "onDeviceDisconnected---销毁刷卡器");
		stopOperation();
		mIsSwiperOK = false;
		mContext = null;
		selectApplication = null;
		if (swiperController != null) {
			// 删除控制器CSwiperController,释放资源
			swiperController.clearSwiperController();
			swiperController = null;
		}
	}

	@Override
	public void onDeviceListRefresh(List<DcBleDevice> arg0) {
		HPLog.i(TAG, "onDeviceListRefresh---" + arg0);
	}

	@Override
	public void onDeviceScanStopped() {
		HPLog.i(TAG, "onDeviceScanStopped");
	}

	@Override
	public void onDeviceScanning() {
		HPLog.i(TAG, "onDeviceScanning");
	}

	@Override
	public void onError(int arg0) {
		HPLog.i(TAG, "onError" + arg0);
		mData = null;
		if (mLock != null) {
			mLock.unlock(AsynSwiperLock.IDLE);
		}
	}

	@Override
	public void onNeedInsertICCard() {
		HPLog.i(TAG, "onNeedInsertICCard");
		mHTData.put("DW_TRADE", "2");
		mLock.unlock(AsynSwiperLock.NEW_SWIPE_CARD);

	}

	@Override
	public void onReturnCardInfo(Map<String, String> cardInfos) {
		HPLog.i(TAG, "onReturnCardInfo");
		String isIC = cardInfos.get(CSwiperController.DCSWIPER_RETURN_MAP_KEY_ICCARDFLAG);
		HPLog.e(HPLog.FDL_TAG, "isIC" + isIC);
		if (isIC != null && isIC.equals("01")) {
			mHTData.put("cardType", cardInfos.get(CSwiperController.DCSWIPER_RETURN_MAP_KEY_ICCARDFLAG));
			mHTData.put(IBusinessSwiper.BANK_PLAIN_ACCOUNT_KEY, cardInfos.get(CSwiperController.DCSWIPER_RETURN_MAP_KEY_ACCOUNT1));
			mHTData.put(IBusinessSwiper.BANK_DYNAMIC_KEY, cardInfos.get(CSwiperController.DCSWIPER_RETURN_MAP_KEY_RAMDOM));
			mHTData.put(IBusinessSwiper.BANK_PLAIN_EXPIRE_DATE, cardInfos.get(CSwiperController.DCSWIPER_RETURN_MAP_KEY_EXPIRED));
			mHTData.put(IBusinessSwiper.BANK_TRACK2_KEY, cardInfos.get(CSwiperController.DCSWIPER_RETURN_MAP_KEY_TRACK2));
			String IcNumber = cardInfos.get(CSwiperController.DCSWIPER_RETURN_MAP_KEY_CRDSQN);
			String DcData = cardInfos.get(CSwiperController.DCSWIPER_RETURN_MAP_KEY_ICDATA);
			if (IcNumber != null && DcData != null) {
				mHTData.put(IBusinessSwiper.BANK_ICNUMBER, IcNumber);
				mHTData.put(IBusinessSwiper.BANK_DCDATA, DcData);
			}
		} else {
			mHTData.put("cardType", cardInfos.get(CSwiperController.DCSWIPER_RETURN_MAP_KEY_ICCARDFLAG));
			mHTData.put(IBusinessSwiper.BANK_PLAIN_ACCOUNT_KEY, cardInfos.get(CSwiperController.DCSWIPER_RETURN_MAP_KEY_ACCOUNT1));
			mHTData.put(IBusinessSwiper.BANK_TRACK2_KEY, cardInfos.get(CSwiperController.DCSWIPER_RETURN_MAP_KEY_TRACK2));
			mHTData.put(IBusinessSwiper.BANK_DYNAMIC_KEY, cardInfos.get(CSwiperController.DCSWIPER_RETURN_MAP_KEY_RAMDOM));
			mHTData.put(IBusinessSwiper.BANK_PLAIN_EXPIRE_DATE, cardInfos.get(CSwiperController.DCSWIPER_RETURN_MAP_KEY_EXPIRED));
		}
		HPLog.i(TAG, "onReturnCardInfo" + mHTData);

		mLock.unlock(AsynSwiperLock.NEW_SWIPE_CARD);

	}

	@Override
	public void onReturnDeviceInfo(Map<String, String> deviceInfos) {
		HPLog.e(TAG, "onReturnDeviceInfo" + deviceInfos.get("KSN"));
		swiperCSN = deviceInfos.get("KSN");
		mLock.unlock(AsynSwiperLock.GETCSN);
	}

	@Override
	public void onTimeout() {
		HPLog.i(TAG, "onTimeout");
	}

	@Override
	public void onWaitingForCardSwipe() {
		HPLog.i(TAG, "onWaitingForCardSwipe");
	}

	@Override
	public void onWaitingForDevice() {
		HPLog.i(TAG, "onWaitingForDevice");
	}



	@Override
	public void onPressCancleKey() {

	}

	@Override
	public void onReturnPinBlock(String s) {

	}


}
